#pragma warning(disable:4786)
#include <vector>
#include <map>
#include <stdio.h>
#include <iostream>
#include <string>

using namespace std;


class Point {
public:
	Point(): xval(0), yval(0) { }
	Point(int x, int y): xval(x), yval(y) {}
	int x() const { return xval; }
	int y() const { return yval; }
	Point& x(int xv) { xval = xv; return *this; }
	Point& y(int yv) { yval = yv; return *this; }

private:
	int xval, yval;
};


class UPoint {
	friend class Handle;
	Point p;
	int u;

	UPoint(): u(1) { }
	UPoint(int x, int y): p(x, y), u(1) { }
	UPoint(const Point& p0): p(p0), u(1) { }
};

class Handle {
public:
	Handle();
	Handle(int, int);
	Handle(const Point&);
	Handle(const Handle&);
	Handle& operator=(const Handle&);
	~Handle();
	int x() const;
	//Handle& x(int);
	int y() const;
	//Handle& y(int);
	Handle& x(int xv);// { up->p.x(xv); return *this; }
	Handle& y(int yv);// { up->p.y(yv); return *this; }

private:
	UPoint *up;
};

Handle::Handle(): up(new UPoint) { }
Handle::Handle(int x, int y): up(new UPoint(x, y)) { }
Handle::Handle(const Point& p): up(new UPoint(p)) { }
Handle::~Handle()
{
	cout << "desconstructor " << endl;
	if (--up->u == 0)
	{
		delete up;
		cout << "delete " << endl;
	}
}

Handle::Handle(const Handle& h): up(h.up) { ++up->u; }

Handle& Handle::operator =(const Handle& h)
{
	++h.up->u;
	if (--up->u == 0)
	{
		delete up;
	}
	up = h.up;
	return *this;
}

Handle& Handle::x(int x0)
{
	if (up->u != 1)
	{
		--up->u;
		up = new UPoint(up->p);	
	}
	up->p.x(x0);
	return *this;
}
Handle& Handle::y(int y0)
{
	if (up->u != 1)
	{
		--up->u;
		up = new UPoint(up->p);	
	}
	up->p.y(y0);
	return *this;
}


int Handle::x() const { return up->p.x(); }
int Handle::y() const { return up->p.y(); }


void main()
{
	Handle h(3, 4);

	cout << h.x() << "  " << h.y() << endl;
	Handle h2 = h;
	h2.x(6);
	cout << h2.x() << "  " << h2.y() << endl;
}
